<?php

namespace App\Http\Services;

use App\Exceptions\Fail;
use App\Http\Services\Admin\UserService;
use App\Models\Admin\RoleModel;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Support\Facades\Cache;
use Mews\Captcha\Facades\Captcha;

class AuthService implements Service
{
    protected Application $app;

    protected array|null $user = [];

    protected string $token = '';

    const Token_Expire = 43200;

    public function __construct(Application $app)
    {
        $this->app = $app;
    }

    public function user(string $key = ''): mixed
    {
        if ($key) {
            return $this->user[$key] ?? '';
        }
        return $this->user;
    }

    public function setUser(array $user): void
    {
        $this->user = $user;
    }

    public function isAdmin(): bool
    {
        if (!$this->user('roles')) return false;
        foreach ($this->user('roles') as $role) {
            if ($role['id'] == RoleModel::Role_Admin) {
                return true;
            }
        }
        return false;
    }

    /**
     * @throws Fail
     */
    public function login(array $params): array
    {
        if (!Captcha::check_api($params['captcha']['code'], $params['captcha']['key'])) {
            request()->replace([]);
            throw new Fail("验证码错误或已过期");
        }
        $this->user = (new UserService)->getUserByAccount($params['account']);
        if (!$this->user) throw new Fail('账号或密码错误');
        if (!password_verify($params['password'], $this->user['password'])) throw new Fail('账号或密码错误');
        $this->user['password'] = md5('sb');
        $this->enableCache();
        $data['token'] = $this->token;
        return $data;
    }

    protected function enableCache()
    {
        Cache::put($this->getToken(), $this->user, self::Token_Expire);
    }

    public function disableCache()
    {
        Cache::forget($this->token);
        unset($this->user);
        unset($this->token);
    }

    protected function getToken(): string
    {
        if ($this->token) {
            return $this->token;
        } else {
            $this->token = md5($this->user('id') . time());
        }
        return $this->token;
    }

    public function validateToken(string $token): bool
    {
        $bool = Cache::has($token);
        if ($bool) {
            $this->user = Cache::get($token);
            $this->token = $token;
            $this->enableCache();
        }
        return $bool;
    }
}
